import { FC, useEffect } from "react";
// #1
import { Outlet, useLoaderData, Form, redirect, NavLink, useNavigation, LoaderFunctionArgs, useSubmit, useParams, useFetchers } from "react-router-dom";
import { getContacts, createContact } from "@/contacts";

const Root: FC = () => {
  const { contacts, q } = useLoaderData() as {
    contacts: ContactType[];
    q: string;
  };
  const navigation = useNavigation();
  const loading = navigation.location && new URLSearchParams(navigation.location.search).has("q");
  const submit = useSubmit();
  // #3
  const params = useParams();
  console.log(params.id);
  const fetchers = useFetchers();
  const updateFavorteFetcher = fetchers.find((item) => item.key === "update-favorite");
  if (updateFavorteFetcher && updateFavorteFetcher.formData) {
    const state = updateFavorteFetcher.formData.get("favorite") === "true";
    contacts.some((item) => {
      if (item.id === params.id) {
        item.favorite = state;
        return true;
      }
    });
  }

  useEffect(() => {
    const ipt = document.getElementById("q")! as HTMLInputElement;
    ipt.value = q;
    ipt.focus();
  }, [q]);
  const renderContacts = () => {
    if (contacts.length === 0)
      return (
        <p>
          <i>No contacts</i>
        </p>
      );
    return (
      <ul>
        {contacts.map((contact) => {
          return (
            <li key={contact.id}>
              <NavLink
                to={`/contacts/${contact.id}`}
                className={({ isActive, isPending }) => {
                  return isActive ? "my-active" : isPending ? "my-pending" : "";
                }}
              >
                {contact.first || contact.last ? (
                  <>
                    {contact.first} {contact.last}
                  </>
                ) : (
                  "No name"
                )}
                {contact.favorite && <span>★</span>}
              </NavLink>
            </li>
          );
        })}
      </ul>
    );
  };
  return (
    <>
      <div id="sidebar">
        <h1>React Router Contacts</h1>
        <div>
          <Form id="search-form" role="search">
            {/* #1 首次搜索应该是 false，后续应该是 true */}
            <input
              className={loading ? "loading" : ""}
              type="search"
              id="q"
              aria-label="Search contacts"
              placeholder="Search"
              name="q"
              defaultValue={q}
              onChange={(e) => {
                // const isFirstSearch = e.currentTarget.value.length === 1
                // // submit(e.currentTarget.form, { replace: isFirstSearch ? false: true })
                // submit(e.currentTarget.form, { replace: !isFirstSearch })
                // 如果删的还剩 length 为 1，上面的代码就有问题了
                const isFirstSearch = e.currentTarget.value.length === 1 && q === "";
                console.log(isFirstSearch, 2);
                submit(e.currentTarget.form, { replace: !isFirstSearch });
              }}
            />
            <div id="search-spinner" aria-hidden hidden={!loading}></div>
            <div className="sr-only" aria-live="polite"></div>
          </Form>
          {/* 新增联系人，提交到路由 path 为 / 的 action 函数进行处理 */}
          <Form method="post" action="/">
            <button type="submit">New</button>
          </Form>
        </div>
        <nav>{renderContacts()}</nav>
      </div>
      <div id="detail" className={navigation.state === "loading" ? "loading" : ""}>
        <Outlet />
      </div>
    </>
  );
};

export const loader = async ({ request }: LoaderFunctionArgs) => {
  const url = new URL(request.url);
  const q = url.searchParams.get("q") || "";
  const contacts = await getContacts(q);
  return {
    contacts,
    q,
  };
};

// 只要 action 函数成功执行，就会自动调用 loader 重新加载数据
export const action = async () => {
  const contact = await createContact();
  return redirect(`/contacts/${contact.id}/edit`);
};

export default Root;
